package com.todo.admin.config;

import com.google.common.util.concurrent.UncheckedExecutionException;
import com.todo.admin.common.base.dto.ResponseDTO;
import com.todo.admin.common.exception.ApiException;
import com.todo.admin.common.exception.error.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;

/**
 * @author azhebuxing
 * @date 2024/12/14 21:47
 * @description
 */
@Slf4j
@Aspect
@Component
public class AdminExceptionAspect {

    /**
     * 环绕
     * 处理异常的自定义处理
     *
     * @param joinPoint
     * @return
     */
    @Around("execution(* com.todo.admin.controller..*.*(..))")
    public Object aroundBiz(ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed;
        try {
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            log.error("请求处理：{}-方法异常，异常数据：{}", signature.getMethod(), throwable.getMessage());
            if (throwable instanceof AccessDeniedException) {
                return ResponseDTO.fail(new ApiException(ErrorCode.Business.PERMISSION_NOT_ALLOWED_TO_OPERATE));
            } else if (throwable instanceof HttpRequestMethodNotSupportedException) {
                return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_METHOD_INVALID, throwable.getMessage()));
            } else if (throwable instanceof ApiException) {
                return ResponseDTO.fail(((ApiException) throwable), ((ApiException) throwable).getPayload());
            } else if (throwable instanceof UncheckedExecutionException) {
                return ResponseDTO.fail(new ApiException(ErrorCode.Internal.GET_CACHE_FAILED, throwable.getMessage()));
            } else if (throwable instanceof BindException) {
                return ResponseDTO.fail(new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, throwable.getMessage()));
            }
            return ResponseDTO.fail(new ApiException(ErrorCode.Internal.INTERNAL_ERROR, throwable.getMessage()));
        }
        return proceed;
    }
}
